/* FreeRTOS头文件 */
 #include "FreeRTOS.h"
 #include "task.h"
 #include "queue.h"
 #include "semphr.h"

 #include <stdint.h>
 #include <stdio.h>

 #include <lwip/sockets.h>

 #include "iperf.h"

 #include "lwip/opt.h"

 #include "lwip/sys.h"
 #include "lwip/api.h"

 #define IPERF_PORT          5001
 #define IPERF_BUFSZ         (4 * 1024)

 void iperf_server(void *thread_param)
 {
     struct netconn *conn, *newconn;
     err_t err;
     void* recv_data;

    printf("iperf_server_Start \r\n");
     recv_data = (void *)pvPortMalloc(IPERF_BUFSZ);
     if (recv_data == NULL)    {
         printf("No memory\n");
     }

    printf("iperf_server_Malloc \r\n");
     conn = netconn_new(NETCONN_TCP);
     netconn_bind(conn, IP_ADDR_ANY, 5001);

    printf("iperf_server_bind %0x\r\n",conn);
     LWIP_ERROR("tcpecho: invalid conn", (conn != NULL), return;);

     /* Tell connection to go into listening mode. */
     netconn_listen(conn);
    printf("iperf_server_listen \r\n");
     while (1)
     {

         /* Grab new connection. */
         err = netconn_accept(conn, &newconn);
         /*printf("accepted new connection %p\n", newconn);*/
         /* Process the new connection. */
         if (err == ERR_OK)
         {
             struct netbuf *buf;
 //      void *data;
             u16_t len;

             while ((err = netconn_recv(newconn, &buf)) == ERR_OK)
             {
                 /*printf("Recved\n");*/
                 do
                 {
                     netbuf_data(buf, &recv_data, &len);
 //             err = netconn_write(newconn, data, len, NETCONN_COPY);
                 }
                 while (netbuf_next(buf) >= 0);
                 netbuf_delete(buf);
             }
             /*printf("Got EOF, looping\n");*/
             /* Close connection and discard connection identifier. */
             netconn_close(newconn);
             netconn_delete(newconn);
         }
         osDelay(40);
     }
 }

 static void iperf_client(void *thread_param)
 {
     struct netconn *conn;

     int i;

     int ret;

     uint8_t *send_buf;

     uint64_t sentlen;

     u32_t tick1, tick2;
     ip4_addr_t ipaddr;


     send_buf = (uint8_t *) pvPortMalloc(IPERF_BUFSZ);
     if (!send_buf) return ;

     for (i = 0; i < IPERF_BUFSZ; i ++)
         send_buf[i] = i & 0xff;

     while (1)
     {
         conn = netconn_new(NETCONN_TCP);
         if (conn == NULL)
         {
             printf("create conn failed!\n");
             vTaskDelay(10);
             continue;
         }

         IP4_ADDR(&ipaddr,192,168,1,247);

         ret = netconn_connect(conn,&ipaddr,5001);
         if (ret == -1)
         {
             printf("Connect failed!\n");
             netconn_close(conn);
             vTaskDelay(10);
             continue;
         }

         printf("Connect to iperf server successful!\n");

         tick1 = sys_now();
         while (1)
         {
            tick2 = sys_now();

            if (tick2 - tick1 >= configTICK_RATE_HZ * 20)
            {
                float f;
                f = (float)(sentlen*configTICK_RATE_HZ/125/(tick2 - tick1));
                f /= 1000.0f;
                printf("send speed = %.4f Mbps!\n", f);

                tick1 = tick2;
                sentlen = 0;
            }
            ret = netconn_write(conn,send_buf,IPERF_BUFSZ,0);
            if (ret == ERR_OK)
            {
                sentlen += IPERF_BUFSZ;
            }

         }
         osDelay(1);
 //    netconn_close(conn);
 //    netconn_delete(conn);
     }
 }

 void iperf_server_init(void)
 {
    // sys_thread_new("iperf_server", iperf_server, NULL, 256, osPriorityRealtime);
    // sys_thread_new("iperf_server", iperf_client, NULL, 512, osPriorityRealtime);
 }

